
#include <stm32f103.h>

#define GPIOA_BASE			(APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE			(APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE			(APB2PERIPH_BASE + 0x1000)

typedef struct
{
	__IO uint32_t CRL;
	__IO uint32_t CRH;
	__IO uint32_t IDR;
	__IO uint32_t ODR;
	__IO uint32_t BSRR;
	__IO uint32_t BRR;
	__IO uint32_t LCKR;
} GPIO_TypeDef;

static GPIO_TypeDef *GPIOx[] = {(GPIO_TypeDef *)GPIOA_BASE, (GPIO_TypeDef *)GPIOB_BASE, (GPIO_TypeDef *)GPIOC_BASE};

int gpio_mode(unsigned int gpio, unsigned int bit, unsigned int mode)
{
	if(8 > bit)
	{
		GPIOx[gpio]->CRL &= ~(0xF << (bit * 4));
		GPIOx[gpio]->CRL |= mode << (bit * 4);
	}
	else if(16 > bit)
	{
		GPIOx[gpio]->CRH &= ~(0xF << ((bit - 8) * 4));
		GPIOx[gpio]->CRH |= mode << ((bit - 8) * 4);
	}
	else
	{
		return -1;
	}
	return 0;
}

int gpio_set(unsigned int gpio, unsigned int bit)
{
	if(16 > bit)
	{
		GPIOx[gpio]->BSRR |= 1 << bit;
		return 0;
	}
	return -1;
}

int gpio_clr(unsigned int gpio, unsigned int bit)
{
	if(16 > bit)
	{
		GPIOx[gpio]->BRR |= 1 << bit;
		return 0;
	}
	return -1;
}